from datetime import datetime
import cnlunar
import re
import logging
from plugins_func.register import register_function, ToolType, ActionResponse, Action
from core.handle.sendAudioHandle import send_topic_message, send_stt_message
from core.utils.dialogue import Message
from core.providers.tts.dto.dto import TTSMessageDTO, SentenceType, ContentType
from core.handle.cacheModule import shared_cache

# 配置日志
logger = logging.getLogger(__name__)

# 函数描述 - 更清晰地定义参数和功能
chuli_zl_function_desc = {
    "type": "function",
    "function": {
        "name": "chuli_zl",
        "description": "控制按摩设备对指定身体部位进行按摩，支持调节按摩强度",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "需要按摩的身体部位，可选值：颈部、腰部、背部、坐骨神经",
                },
                "intensity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "default": 3,
                    "description": "按摩强度等级，1级（最弱）到5级（最强），默认3级"
                 }
            },
            "required": ["query"],
        },
    },
}


@register_function("chuli_zl", chuli_zl_function_desc, ToolType.TOPIC_CTL)
def chuli_zl(conn, query=None, intensity=None):
    """
    处理按摩服务请求，包括部位验证、强度设置和服务确认
    
    参数:
        query: 包含按摩部位的用户请求
        intensity: 按摩强度(1-5级)，默认3级
    """
    logger.info(f"处理按摩请求: query={query}, intensity={intensity}")
    
    # 验证用户权限
    auth_result, auth_message = _validate_user_permission(conn)
    if not auth_result:
        return ActionResponse(Action.RESPONSE, "权限验证失败", auth_message)
    
    # 配置允许的按摩部位及友好提示（与描述保持一致）
    ALLOWED_PARTS = {"颈部", "腰部", "背部", "坐骨神经"}
    PART_PROMPT = ", ".join(ALLOWED_PARTS)
    
    # 处理空查询
    if not query or not query.strip():
        return ActionResponse(
            Action.REQLLM, 
            f"请问需要按摩哪个部位？我们提供{PART_PROMPT}的按摩服务。", 
            None
        )
    
    # 检查敏感内容
    if _contains_sensitive_content(query):
        logger.warning(f"检测到敏感内容: {query}")
        return ActionResponse(Action.REQLLM, "抱歉，无法提供此类服务。", None)
    
    # 从用户输入中提取按摩部位和强度
    part, extracted_intensity = _extract_part_and_intensity(query, ALLOWED_PARTS)
    
    # 如果未通过参数提供强度，但从查询中提取到了，则使用提取的值
    if intensity is None and extracted_intensity is not None:
        intensity = extracted_intensity
    
    # 验证按摩部位
    if not part or part not in ALLOWED_PARTS:
        return ActionResponse(
            Action.REQLLM, 
            f"抱歉，目前仅支持{PART_PROMPT}的按摩服务，请问需要哪项？", 
            None
        )
    
    # 处理强度参数
    if intensity is None:
        # 未提供强度，询问用户
        return ActionResponse(
            Action.REQLLM, 
            f"已为您安排{part}按摩。请选择强度（1-5级，默认3级）：", 
            None
        )
    else:
        # 验证强度类型和范围
        try:
            intensity = int(intensity)
            if not (1 <= intensity <= 5):
                raise ValueError("强度超出范围")
        except ValueError:
            return ActionResponse(
                Action.REQLLM, 
                "强度设置无效，请选择1-5级的强度（1级最弱，5级最强）。", 
                None
            )
        
        # 确认服务（这里可以添加实际控制设备的逻辑）
        response_text = f"已启动{part}按摩，强度为{intensity}级。如需调整，请随时告知。"
        
        # 发送消息到设备
        conn.loop.create_task(
            send_stt_message_async(conn, response_text, 'topic')
        )
        
        logger.info(f"按摩已启动: 部位={part}, 强度={intensity}")
        return ActionResponse(
            Action.REQLLM, 
            response_text, 
            None
        )


def _validate_user_permission(conn):
    """验证用户是否有权限控制按摩设备"""
    speaker = shared_cache.get("speaker")
    if speaker is None:
        logger.warning("未检测到开机用户")
        return False, "抱歉，请先扫码开机按摩"
        
    if conn.current_speaker != speaker:
        logger.warning(f"用户权限验证失败: 开机按摩用户={speaker}, 识别到的用户={conn.current_speaker}")
        str_=f"抱歉{conn.current_speaker},我在帮别人按摩，我不能听你的。"
        if(speaker=='不可靠说话人'):
            str_="抱歉，你不是按摩客人，我不能听你的。"
        if(speaker=='未知说话人'):
            str_="抱歉，我不认识您，我不能听你的。"
        return False, str_

        
    return True, ""


def _contains_sensitive_content(text):
    """检查文本中是否包含敏感内容"""
    sensitive_patterns = r"生殖器|私密|隐私|阴部|乳房|乳头"
    return re.search(sensitive_patterns, text, re.IGNORECASE) is not None


def _extract_part_and_intensity(query, allowed_parts):
    """从查询中提取按摩部位和强度"""
    # 提取部位
    part_match = re.search(rf"({'|'.join(allowed_parts)})", query)
    part = part_match.group(1) if part_match else None
    
    # 提取强度（支持"X级"或"强度X"等表达方式）
    intensity_match = re.search(r"(\d+)(级|强度)", query)
    intensity = int(intensity_match.group(1)) if intensity_match else None
    
    return part, intensity


async def send_stt_message_async(conn, text, msg_type):
    """异步发送STT消息并处理可能的异常"""
    try:
        await send_topic_message(conn, text, msg_type)
        logger.info(f"已发送消息: {text}")
    except Exception as e:
        logger.error(f"发送消息失败: {str(e)}")
